package com.yunhe.abnormal.repository.base.impl;

import com.google.common.collect.Lists;
import com.yunhe.abnormal.domain.base.AlarmNotifyConfig;
import com.yunhe.abnormal.repository.base.AlarmNotifyConfigSession;
import com.yunhe.common.util.Neo4jConditionUtil;
import com.yunhe.common.util.StringUtil;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 异常通知配置Session实现类
 * @author liuronglei
 */
@Repository
public class AlarmNotifyConfigSessionImpl implements AlarmNotifyConfigSession {
    @Autowired
    private Session session;

    @Override
    public List<AlarmNotifyConfig> search(Integer type, Long alarmLevelId, String alarmNotifyTypeName, Long firmId, Long userId) {
        StringBuilder query = new StringBuilder("match(anc:AlarmNotifyConfig)");
        List<String> condition = new ArrayList<>();
        HashMap<String, Object> params = new HashMap<>();
        if (type != null) {
            condition.add("anc.type={type}");
            params.put("type", type);
        }
        if (alarmLevelId != null) {
            query.append(",(anc)-[:ALARM_LEVEL_OF]->(al:AlarmLevel)");
            condition.add("id(al)={alarmLevelId}");
            params.put("alarmLevelId", alarmLevelId);
        }
        if (!StringUtil.isEmpty(alarmNotifyTypeName)) {
            query.append(",(anc)-[:ALARM_NOTIFY_TYPE_OF]->(ant:AlarmNotifyType)");
            condition.add("ant.name={alarmNotifyTypeName}");
            params.put("alarmNotifyTypeName", alarmNotifyTypeName);
        }
        if (firmId != null) {
            query.append(",(anc)-[:FIRM_OF]->(f:Firm)");
            condition.add("id(f)={firmId}");
            params.put("firmId", firmId);
        }
        if (userId != null) {
            query.append(",(anc)-[:USER_OF]->(u:User)");
            condition.add("id(u)={userId}");
            params.put("userId", userId);
        }
        query.append(Neo4jConditionUtil.getConditionStr(condition)).append(" return anc")
                .append(",(anc)-[:FIRM_OF]->(:Firm)")
                .append(",(anc)-[:ALARM_LEVEL_OF]->(:AlarmLevel)")
                .append(",(anc)-[:STATION_OF]->(:Station)")
                .append(",(anc)-[:ALARM_NOTIFY_TYPE_OF]->(:AlarmNotifyType)")
                .append(",(anc)-[:USER_OF]->(:User)")
                .append(" order by anc.sn");
        return Lists.newArrayList(session.query(AlarmNotifyConfig.class, query.toString(), params));
    }

    @Override
    public void unBindRelat(Long alarmNotifyConfigId) {
        String query = "match(anc:AlarmNotifyConfig)-[r]->(n) where id(anc)={alarmNotifyConfigId} delete r";
        Map<String, Object> params = new HashMap<>();
        params.put("alarmNotifyConfigId", alarmNotifyConfigId);
        session.query(query, params);
    }

    @Override
    public void bindRelat(AlarmNotifyConfig alarmNotifyConfig) {
        List<String> match = new ArrayList<>();
        List<String> condition = new ArrayList<>();
        List<String> create = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("alarmNotifyConfigId", alarmNotifyConfig.getId());
        if (alarmNotifyConfig.getAlarmLevel() != null) {
            match.add("(al:AlarmLevel)");
            condition.add("id(al)={alarmLevelId}");
            create.add("(anc)-[:ALARM_LEVEL_OF]->(al)");
            params.put("alarmLevelId", alarmNotifyConfig.getAlarmLevel().getId());
        }
        if (alarmNotifyConfig.getAlarmNotifyType() != null) {
            match.add("(ant:AlarmNotifyType)");
            condition.add("id(ant)={alarmNotifyTypeId}");
            create.add("(anc)-[:ALARM_NOTIFY_TYPE_OF]->(ant)");
            params.put("alarmNotifyTypeId", alarmNotifyConfig.getAlarmNotifyType().getId());
        }
        if (alarmNotifyConfig.getUser() != null) {
            match.add("(u:User)");
            condition.add("id(u)={userId}");
            create.add("(anc)-[:USER_OF]->(u)");
            params.put("userId", alarmNotifyConfig.getUser().getId());
        }
        if (alarmNotifyConfig.getFirm() != null) {
            match.add("(f:Firm)");
            condition.add("id(f)={firmId}");
            create.add("(anc)-[:FIRM_OF]->(f)");
            params.put("firmId", alarmNotifyConfig.getFirm().getId());
        }
        if (alarmNotifyConfig.getStations() != null) {
            List<Long> stationId = new ArrayList<>();
            alarmNotifyConfig.getStations().forEach(item -> stationId.add(item.getId()));
            match.add("(s:Station)");
            condition.add("id(s) in {stationId}");
            create.add("(anc)-[:STATION_OF]->(s)");
            params.put("stationId", stationId);
        }
        for (int i = 0; i < match.size(); i++) {
            String query = "match(anc:AlarmNotifyConfig)," + match.get(i) + " where id(anc)={alarmNotifyConfigId} and " + condition.get(i) +
                    " create " + create.get(i);
            session.query(query, params);
        }
    }

    @Override
    public void deleteNotifyConfigByUserId(Long userId) {
        String query = "match(anc:AlarmNotifyConfig) where anc.relatedUserId={userId} detach delete anc";
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        session.query(query, params);
    }

    @Override
    public void deleteSmsConfigByUserId(Long userId) {
        String query = "match(asc:AlarmSmsConfig) where asc.relatedUserId={userId} detach delete asc";
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        session.query(query, params);
    }

    @Override
    public void deleteByFirmId(Long firmId) {
        Map<String, Object> params = new HashMap<>();
        params.put("firmId", firmId);
        String query = "match(asc:AlarmSmsConfig)<-[:SMS_DEST_OF]-(anc:AlarmNotifyConfig) where anc.relatedFirmId={firmId} detach delete asc";
        session.query(query, params);
        query = "match(anc:AlarmNotifyConfig) where anc.relatedFirmId={firmId} detach delete anc";
        session.query(query, params);
    }
}
